<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>

</html>
<script>
    // JS的解析过程分为两个阶段：预编译期(预处理)与执行期。
    // 第一阶段(预编译期)：
    // 1、先找var和function关键字，如果找到var关键字，提前赋值undefined给变量名.  如果找到function，提前将整个函数赋值给函数名称
    // 2、如果函数和变量出现重名，函数优先。
    // 3、函数的参数类似于变量，函数内部同样做预解析，支持预解析。
    // 4、if语句和for语句里面的变量和函数做预解析提前赋值undefined,函数声明不会跳过。

    // 第二阶段(执行期)：在编译后的基础上开始从上到下执行脚本，遇到错误时中断。
    // 正常情况下(排除if、for)， 普通函数声明跳过， 变量声明未初始化跳过(var a)。 

    // 预编译后的结果：
    // function a() {alert(5);}



    // alert(a); //function a() {alert(5);}
    // a(); //5
    // var a = 3;

    // function a() {
    //     alert(10);
    // }
    // alert(a); //3

    // function a() {
    //     alert(5);
    // }
    // a = 6;
    // alert(a); //6
    // var a = function() {
    //     alert(8);
    // }
    // a(); //8




    //预编译的结果：
    //var b = undefined
    // function a(b) { //var b = 100
    //     console.log(b); //100
    //     var b = 1;
    //     console.log(b); //1
    // }
    // a(100)


    //预编译的结果：
    // var b = undefined
    // function a(b) { //var b = 100   里面没有函数，这里先执行(预编译结果是变量)
    //     var b;
    //     console.log(b); //100
    //     b = 1;
    //     console.log(b); //1
    // }
    // a(100)

    //预编译的结果：
    //b =  function b() {};

    //总结：如果函数内部预编译的结果是函数优先，内部的函数提升到可见的代码的第一行
    // function a(b) { //这里是形参，相当于 var b = 100 ，自己理解的，不可见
    //     //函数提升到这里， function b() {}
    //     console.log(b);
    //     b = 1;

    //     function b() {}; //这里的函数提升
    //     console.log(b);
    // }
    // a(100)

    // var a = 10;

    // function fn(a) {
    //     //函数提升到这里， function a() {}
    //     console.log(a);

    //     function a() {}
    // }
    // fn(a);


    //预编译的结果：
    //a = undefined - a函数再if语句里面
    //b = undefined - 变量提升
    //c = undefined - c函数再if语句里面
    //d = undefined - 变量提升
    // function fn() {
    //     console.log(a); //undefined 
    //     console.log(b); //undefined 
    //     console.log(c); //undefined 
    //     console.log(d); //undefined 
    //     if (false) { //逐行执行跳过，预编译要做的。
    //         function a() {};
    //         var b = 1;
    //     }
    //     if (true) {
    //         function c() {};
    //         var d = 1;
    //     }
    //     console.log(a); //undefined 
    //     console.log(b); //undefined
    //     console.log(c); // function c() {};
    //     console.log(d); // 1
    // }
    // fn()
</script>